﻿using MD5Hash;
using MediatR;
using Microsoft.IdentityModel.Tokens;
using SmartCity.Passport.API.Application.Commands;
using SmartCity.Passport.API.DTO;
using SmartCity.Passport.API.ErrorCode;
using SmartCity.Passport.API.Extensions;
using SmartCity.Passport.Domain.Entites;
using SmartCity.Passport.ErrorCode;
using SmartCity.Passport.Infrastructure.Interfaces;
using System.IdentityModel.Tokens.Jwt;
using System.Text;

namespace SmartCity.Passport.API.Application.CommandHandlers
{
    public class LoginCommandHandler : IRequestHandler<LoginCommand, ApiResult<UserDto>>
    {
        /// <summary>
        /// 用户仓储
        /// </summary>
        private readonly IBaseRepository<User> userRep;
        /// <summary>
        /// 角色仓储
        /// </summary>
        private readonly IBaseRepository<Role> roleRep;
        /// <summary>
        /// 角色用户仓储
        /// </summary>
        private readonly IBaseRepository<RoleUser> roleUserRep;
        private readonly IBaseRepository<Permission> permissionRep;
        private readonly IBaseRepository<RolePermission> rolePermissionRep;

        public LoginCommandHandler(IBaseRepository<User> userRep, IBaseRepository<Role> roleRep, IBaseRepository<RoleUser> roleUserRep,IBaseRepository<Permission> permissionRep,IBaseRepository<RolePermission> rolePermissionRep)
        {
            this.userRep = userRep;
            this.roleRep = roleRep;
            this.roleUserRep = roleUserRep;
            this.permissionRep = permissionRep;
            this.rolePermissionRep = rolePermissionRep;
        }


        /// <summary>
        /// 处理
        /// </summary>
        /// <param name="request">请求</param>
        /// <param name="cancellationToken">取消</param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Task<ApiResult<UserDto>> Handle(LoginCommand request, CancellationToken cancellationToken)
        {
            ApiResult<UserDto> result = new ApiResult<UserDto>();
            result.code = ApiEnum.LoginSuccess;
            result.message = ApiEnum.LoginSuccess.GetDescription();
            try
            {
                //验证
                if (string.IsNullOrEmpty(request.UserName))
                {
                    throw new Exception("用户名不能为空");
                }
                if (string.IsNullOrEmpty(request.Password))
                {
                    throw new Exception("密码不能为空");
                }
                //MD5不叫加密 是一种对数据的处理技术
                request.Password = request.Password.GetMD5().ToUpper();

                var list = from a in userRep.GetAll()
                           join b in roleUserRep.GetAll() on a.UserId equals b.UserId
                           join c in roleRep.GetAll() on b.RoleId equals c.RoleId
                           where a.UserName == request.UserName && a.Passwprd == request.Password
                           select new UserDto
                           {
                               UserId = a.UserId,
                               UserName = a.UserName,
                               UserNickname = a.UserNickname,
                               Passwprd = a.Passwprd,
                               UserPhone = a.UserPhone,
                               UserEmail = a.UserEmail,
                               RoleId = c.RoleId,
                               RoleName = c.RoleName,
                           };
                var entity = list.FirstOrDefault();
                if (entity == null)
                {
                    throw new Exception("用户名和密码不匹配");
                }
                //生成令牌
                entity.Token = CreateTokenString();
                //获取权限
                var permiassins = from a in roleRep.GetAll()
                                  join b in rolePermissionRep.GetAll() on a.RoleId equals b.RoleId
                                  join c in permissionRep.GetAll() on b.PermissionId equals c.PermissionId
                                  where a.RoleId == entity.RoleId
                                  select new Permission
                                  {
                                      PermissionId = c.PermissionId,
                                      PermissionType = c.PermissionName,
                                      PermissionName = c.PermissionName,
                                      PermissionLevenl = c.PermissionLevenl,
                                      PermissionValue = c.PermissionValue,
                                      PermissionPath = c.PermissionPath,
                                      ParentId = c.ParentId,
                                  };
                entity.permissions = permiassins.ToList();

                result.data = entity;
            }
            catch (Exception ex)
            {
                result.code = ApiEnum.LoginFail;
                result.message = ApiEnum.LoginFail.GetDescription() + ex.Message;
            }

            
            return Task.FromResult(result);
        }
        private string CreateTokenString()
        {
            //私钥
            var secretByte = Encoding.UTF8.GetBytes("kdsfldsflkdslkflkdsflkdslfdslkflk");
            // 非对称加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 使用256 生成数字签名
            var signingCredentials = new SigningCredentials(signingKey, SecurityAlgorithms.HmacSha256);
            // 生成Token
            var token = new JwtSecurityToken(
                issuer: "BeiJingBW",
                audience: "BeiJingBW",
                expires: DateTime.Now.AddDays(1), // 一天后过期
                signingCredentials: signingCredentials
            );
            // 生成token 字符串
            var strToken = new JwtSecurityTokenHandler().WriteToken(token);
            return strToken;
        }
    }
}
